# -*- coding: utf-8 -*-
import xml.etree.ElementTree as etree

TOPES=["ARTE",
       "BIOLOGIA Y MEDIO AMBIENTE",
       "EDUCACION",
       "FILOSOFIA Y RELIGION",
       "HISTORIA",
       "INFORMACION, COMUNICACION Y BIBLIOTECAS",
       "INVESTIGACION, CIENCIA Y TECNOLOGIA",
       "LITERATURA Y LINGUISTICA",
       "MATEMATICA, FISICA Y QUIMICA",
       "MEDICINA Y SALUD",
       "POLITICA, DERECHO Y ECONOMIA",
       "PSICOLOGIA",
       "SOCIEDAD Y CULTURA",
       "TIERRA Y ESPACIO",
       "ZONAS GEOGRAFICAS Y PAISES"]
listaSiglas=["TT:","TG:","USE:","NA:","UP:","TE:"]
flgIDT=0


class TerminoBase(object):

    def __init__(self):
        self.id=0
        self.value=""
        self.tipo=""
        self.relacionados=[]

    def addId(self,id):
        self.id=id
    def addTipo(self,tipo):
        self.tipo=tipo

    def addValor(self,valor):
        """agrega un valor"""
        self.value=valor

    def addRelacion(self,tuplaValor):
        """agrega una tupla (texto,id) a la lista de relacionados"""

        for linea in self.relacionados:
            if linea[2] == tuplaValor[2]:
                return False

        self.relacionados.append(tuplaValor)
        return True

class Termino(TerminoBase):
    """Termino, que es hijo o no de un Termino Tope"""

    def __init__(self):
        super(Termino, self).__init__()
        self.tipo="termino"
        self.padre=""

    def addPadre(self, tuplaValor):
        """agrega una tupla como padre (texto,id) y devuelve true. si padre ya esta seteado, devuelve false"""
        if self.padre!="":
            return False
        else:
            self.padre=tuplaValor
            return True

class TTope(TerminoBase):
    """Termino Tope"""


    def __init__(self):
        super(TTope, self).__init__()
        self.hijos=[]
        self.tipo="ttpe"

    def addHijo(self,tuplaValor):
        """agrega una tupla (texto,id) a la lista de relacionados"""

        for linea in self.hijos:
            if linea[1] == tuplaValor[1]:
                return False

        self.hijos.append(tuplaValor)
        return True

class Tesauro(object):
    """implementacion del tesaurl"""
    listTopes=[]
    listTerminos=[]

    def addTTope(self,ttope):
        for linea in self.listTopes:
            if linea.value==ttope.value:
                return False

        self.listTopes.append(ttope)
        return False

    def getTopeByVal(self,strVal):
        """dado el titulo, devuelve el termino tope"""
        for elem in self.listTopes:
            if elem.value==strVal:
                return elem
        return False

    def addTermino(self,termino):
        for elem in self.listTerminos:
            if elem.value==termino.id:
                return False
        listaTerminos.append(termin)

    def findTTopeByVal(self,val):
        """devuelve un termino tope o falso si no lo encuentra"""

        for elem in self.listTopes:
            if elem.value==val:
                return elem

        return False

    def findTerminoByVal(self,val):
        """devuelve un termino o falso si no lo encuentra"""
        for elem in self.listTerminos:
            if elem.value==val:
                return elem
        return False

    def getPadreTermino(self,termino):
        """devuelve el padre de un termino"""


        for elem in self.listTerminos:
            if elem == termino:
                return elem.padre
        return False

#auxiliares
def leeXML(context):
    """lee el archivo con el tesauro y devuelve el nodo raiz"""
    mixml=etree.parse("src/Products.bpPolicy/Products/bpPolicy/tesauro.xml")
    root=mixml.getroot()
    idFlag=0
    return root

def parseLinea(texto):
    listaT=[]
    lastVal=[]
    posiciones=busca2p(texto)

    while len(posiciones)>0:
        puntero=posiciones[0]

        if len(lastVal)==0:
            subV=texto[:puntero+1]
        else:
            prevVal=lastVal[len(lastVal)-1]
            subV=texto[puntero-3:puntero+1].strip()



        if len(posiciones)>1:
            nextPuntero = posiciones[1]
            subT=texto[puntero+2:nextPuntero-3].strip()
        else:
            subT=texto[puntero+1:].strip()

        listaT.append((subV,subT))
        posiciones.pop(0)
        lastVal.append(puntero)

    return listaT

def busca2p(cadena):
    lista = []
    pos_inicial = -1
    try:
        while True:
            # cada vez buscamos desde un caracter más adelante de
            # la última ocurrencia encontrada
            pos_inicial = cadena.index(':', pos_inicial+1)
            lista.append(pos_inicial)
    except ValueError: # cuando ya no se encuentre la letra
        pass
    return lista

tesauro=Tesauro()

def generaTopes():
    """Recorre la lista de terminos tope y los convierte en objectos TTope"""
    global flgIDT

    for tope in TOPES:
        topObject=TTope()
        topObject.addValor(tope)
        topObject.addId(flgIDT)
        flgIDT+=1
        tesauro.addTTope(topObject)

def generaTesauro(context):
    """Main, genera el tesauro desde un xml"""

    global flgIDT

    termino=""
    terminoHold=""
    terminoPosta=""
    listaTT=[]
    listaTerminos=[]
    idFlag=0
    root=leeXML(context)
    generaTopes()

    for linea in root:
        esNuevoTermino=True

        if linea.text.count(":")>0:
            esNuevoTermino=False



        if esNuevoTermino:
            if len(linea.text)<50:
                termino     =   linea.text.strip()
                listaTerminos.append(termino)
                elTerminoEsTop=tesauro.getTopeByVal(termino)


                if not elTerminoEsTop:
                    ###creando un Termino nuevo
                    terminoHold=Termino()
                    terminoHold.addValor(termino)
                    terminoHold.addId(flgIDT)

        else:
            tmpTerminos=parseLinea(linea.text)
            mitope=None

            for siglaX,valorX in tmpTerminos:
                if siglaX=="TT:":
                    for ttPX in TOPES:
                        for palab in ttPX.split(" "):
                            if valorX==palab:
                                valorX=ttPX
                                break;



                    mitope=tesauro.findTTopeByVal(valorX)

                    if mitope:
                        terminoHold.padre=mitope.value
                        if listaTerminos.count(terminoHold.value)>1:
                            terminoHold.value=terminoHold.value+"__"+str(mitope.id)
                        mitope.addHijo((terminoHold.value,terminoHold.id))


        flgIDT=flgIDT+1
        idFlag+=1


def importTesauroToVocab(context):
    """arma un diccionario para pasarlo a ATVM"""


    generaTesauro(context)

    dccio=dict()

    for ttop in tesauro.listTopes:
        vlor=ttop.value.replace(" ","_").lower()
        vlor=vlor.encode("utf-8").replace(",_","_")
        vlor=vlor.encode("utf-8").replace("_y_","_")
        texto=ttop.value
        dccio[(vlor,texto)]=dameDiccionarioDeHijos(ttop)

    return dccio

def dameDiccionarioDeHijos(ttope):
    diccion=dict()
    #id_t
    for elem in ttope.hijos:
        texto=elem[0].replace(" ","_").lower()
        id_t=texto.replace("_[","_")
        id_t=id_t.replace("]","")
        id_t=id_t.encode("utf-8").replace("ñ","n")
        id_t=id_t.encode("utf-8").replace("-","_")
        id_t=id_t.encode("utf-8").replace("/","_")
        id_t=id_t.encode("utf-8").replace("'","_")
        id_t=id_t.encode("utf-8").replace(",_","_")
        diccion[(id_t,elem[0])]=dict()
    return diccion


#importTesauroToVocab()